package com.zhm.demo.netty.init;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class NettyServerManager {

    private static final Logger log = LoggerFactory.getLogger(NettyServerManager.class);

    @Value("${netty.server.port}")
    private int nettyServerPort;

    private EventLoopGroup bossGroup = null;
    private EventLoopGroup workerGroup = null;
    private ChannelFuture channelFuture;

    //    @PostConstruct
    public void init() {
        startNettyServer();
        stopNettyServer();
    }

    public void startNettyServer() {
        try {

            // 配置服务端的NIO线程组
            /**
             * Boos线程避免竞争 开启1个线程即可
             */
            bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("boss"));
            /**
             *  Runtime 是获取当前现场核心数量从而决定 处理工作线程
             */
            workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2, new DefaultThreadFactory("worker"));
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)//EpollServerSocketChannel NioServerSocketChannel 因为是在Linux运行 选择Epoll进行第一阶段优化
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ServerInit());
            // 绑定端口，同步等待成功
            log.info("Netty server start : " + nettyServerPort);
            channelFuture = b.bind(nettyServerPort).sync();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    public void stopNettyServer() {
        try {
            log.info("Netty server stop : " + nettyServerPort);
            if (channelFuture != null) {
                channelFuture.channel().close().sync();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            // Handle the exception
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
